//package com.turing.post.util;

import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.util.List;

import org.objectweb.asm.ClassReader;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.Method;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.LocalVariableNode;
import org.objectweb.asm.tree.MethodNode;

public class Analyzer {
	@SuppressWarnings("unchecked")
	public static void main(final String[] args) throws Exception {
		DataInputStream input = new DataInputStream(new BufferedInputStream(
				new FileInputStream(args[0])));

		ClassReader cr = new ClassReader(input);
		ClassNode cn = new ClassNode();
		cr.accept(cn, 0/*ClassReader.SKIP_DEBUG*/);

		System.out.println("Class:" + cr.getClassName());

		// we need SuperClass
		System.out.println("SuperClass:" + cr.getSuperName());

		// we need Interfaces
		String[] interfaces = cr.getInterfaces();
		if (interfaces != null && interfaces.length > 0) {
			System.out.println("Interface list(" + interfaces.length + "):");
			for (int i = 0; i < interfaces.length; i++)
				System.out.println("interface:" + interfaces[i]);
		}

		// we need Field
		List<FieldNode> fields = (List<FieldNode>) cn.fields;
		if (fields != null && fields.size() > 0) {
			FieldNode fld = null;
			System.out.println("Fields list(" + fields.size() + "):");
			for (int i = 0; i < fields.size(); ++i) {
				fld = fields.get(i);
				System.out.println(Type.getType(fld.desc).getClassName() + " "
						+ fld.name);
			}
		}

		List<MethodNode> methods = (List<MethodNode>) cn.methods;
		if (methods != null && methods.size() > 0) {
			MethodNode method = null;
			System.out.println("Methods list(" + methods.size() + "):");
			for (int i = 0; i < methods.size(); ++i) {
				method = methods.get(i);

				// 返回值
				System.out.print(Type.getReturnType(method.desc).getClassName()
						+ " " + method.name + "(");
				// 参数
				Type[] margs = Type.getArgumentTypes(method.desc);
				for (int m = 0; m < margs.length; m++) {
					if (m > 0)
						System.out.print(" , ");
					System.out.print(margs[m].getClassName());
				}
				System.out.println(")");

				// 异常
				List<String> mdexcep = (List<String>) method.exceptions;
				if (mdexcep != null && mdexcep.size() > 0) {
					System.out.println("\t Exception: ");
					for (int k = 0; k < mdexcep.size(); k++)
						System.out.println(mdexcep.get(k));
				}

				// 局部变量
				List<LocalVariableNode> lvn = (List<LocalVariableNode>) method.localVariables;
				System.out.println("lvn.size == " + lvn.size());
				if (lvn != null && lvn.size() > 0) {
					System.out.println("\t LocalVariable: ");
					for (int k = 0; k < lvn.size(); k++)
						System.out.println(Type.getType(lvn.get(k).desc)
								.getClassName()
								+ " " + lvn.get(k).name);
				}
			}
		}
	}
}
